Micron Document
<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Error diffusion</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Error_diffusion"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/ext.math.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Error_diffusion rootpage-Error_diffusion skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Error diffusion</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<p><b>Error diffusion</b> is a type of <a href="Halftone" title="Halftone">halftoning</a> in which the <a href="Quantization_(image_processing)" title="Quantization (image processing)">quantization</a> residual is distributed to neighboring <a href="Pixel" title="Pixel">pixels</a> that have not yet been processed. Its main use is to convert a multi-level image into a <a href="Binary_file" title="Binary file">binary</a> image, though it has other applications.
</p><p>Unlike many other halftoning methods, error diffusion is classified as an area operation, because what the algorithm does at one location influences what happens at other locations. This means <a href="Data_buffer" title="Data buffer">buffering</a> is required, and complicates <a href="Parallel_computing" title="Parallel computing">parallel processing</a>. Point operations, such as ordered <a href="Dither" title="Dither">dither</a>, do not have these complications.
</p><p>Error diffusion has the tendency to enhance edges in an image. This can make text in images more readable than in other <a href="Halftone" title="Halftone">halftoning</a> techniques.
</p>

<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="Early_history">Early history</h2></div>
<p><a href="Richard_Howland_Ranger" class="mw-redirect" title="Richard Howland Ranger">Richard Howland Ranger</a> received United States <a href="Patent" title="Patent">patent</a> 1790723 for his <a href="Invention" title="Invention">invention</a>, "Facsimile system". The patent, which issued in 1931, describes a system for transmitting <a href="Image" title="Image">images</a> over telephone or telegraph lines, or by radio.<sup id="cite_ref-Ranger1931_1-0" class="reference"><a href="#cite_note-Ranger1931-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup> Ranger's invention permitted <a href="Continuous_tone" class="mw-redirect" title="Continuous tone">continuous-tone</a> <a href="Photograph" title="Photograph">photographs</a> to be converted first into black and white, then transmitted to remote locations, which had a pen moving over a piece of paper. To render black, the pen was lowered to the paper; to produce white, the pen was raised. Shades of <a href="Gray" class="mw-redirect" title="Gray">gray</a> were rendered by intermittently raising and lowering the pen, depending upon the <a href="Luminance" title="Luminance">luminance</a> of the gray desired.
</p><p>Ranger's invention used capacitors to store charges, and <a href="Vacuum_tube" title="Vacuum tube">vacuum tube</a> comparators to determine when the present luminance, plus any accumulated error, was above a threshold (causing the pen to be raised) or below (causing the pen to be lowered). In this sense, it was an <a href="Analog_electronics" class="mw-redirect" title="Analog electronics">analog</a> version of error diffusion.
</p>
<div class="mw-heading mw-heading2"><h2 id="Digital_era">Digital era</h2></div>
<div class="mw-heading mw-heading3"><h3 id="Floyd-Steinberg">Floyd-Steinberg</h3></div>
<p><a href="Floyd%E2%80%93Steinberg_dithering" title="Floyd–Steinberg dithering">Floyd and Steinberg</a> described a system for performing error diffusion on <a href="Digital_data" title="Digital data">digital</a> images based on a simple kernel<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle {\frac {1}{16}}{\begin{bmatrix}-&amp;\#&amp;7\\3&amp;5&amp;1\end{bmatrix}}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mn>1</mn>
<mn>16</mn>
</mfrac>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mrow>
<mo>[</mo>
<mtable rowspacing="4pt" columnspacing="1em">
<mtr>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
<mtd>
<mi mathvariant="normal">#<!-- # --></mi>
</mtd>
<mtd>
<mn>7</mn>
</mtd>
</mtr>
<mtr>
<mtd>
<mn>3</mn>
</mtd>
<mtd>
<mn>5</mn>
</mtd>
<mtd>
<mn>1</mn>
</mtd>
</mtr>
</mtable>
<mo>]</mo>
</mrow>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle {\frac {1}{16}}{\begin{bmatrix}-&amp;\#&amp;7\\3&amp;5&amp;1\end{bmatrix}}}</annotation>
</semantics>
</math></span><img src="./e24d955dbab139d7d7c27741f284dbce199b649f.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -2.505ex; width:15.919ex; height:6.176ex;" alt="{\displaystyle {\frac {1}{16}}{\begin{bmatrix}-&amp;\#&amp;7\\3&amp;5&amp;1\end{bmatrix}}}" loading="lazy"></span></dd></dl>
<p>where "<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle -}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mo>−<!-- − --></mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle -}</annotation>
</semantics>
</math></span><img src="./04bd52ce670743d3b61bec928a7ec9f47309eb36.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.505ex; width:1.808ex; height:2.176ex;" alt="{\displaystyle -}" loading="lazy"></span>" denotes a pixel in the current row which has already been processed (hence diffusing error to it would be pointless), and "#" denotes the pixel currently being processed. "<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle -}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mo>−<!-- − --></mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle -}</annotation>
</semantics>
</math></span><img src="./04bd52ce670743d3b61bec928a7ec9f47309eb36.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.505ex; width:1.808ex; height:2.176ex;" alt="{\displaystyle -}" loading="lazy"></span>" can be seen as <b>no error diffused</b> or "<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle 0}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mn>0</mn>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle 0}</annotation>
</semantics>
</math></span><img src="./2aae8864a3c1fec9585261791a809ddec1489950.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.162ex; height:2.176ex;" alt="{\displaystyle 0}" loading="lazy"></span>"
</p>
<div class="mw-heading mw-heading3"><h3 id="Jarvis,_Judice_and_Ninke">Jarvis, Judice and Ninke</h3></div>
<p>Nearly concurrently, <b>J. F. Jarvis, C. N. Judice, and W. H. Ninke</b> of <a href="Bell_Labs" title="Bell Labs">Bell Labs</a> disclosed a similar method, which they termed "<b><style data-mw-deduplicate="TemplateStyles:r1238216509">
/* start https://en.wikipedia.org/ */


.mw-parser-output .vanchor>:target~.vanchor-text{background-color:#b1d2ff}@media screen{html.skin-theme-clientpref-night .mw-parser-output .vanchor>:target~.vanchor-text{background-color:#0f4dc9}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .vanchor>:target~.vanchor-text{background-color:#0f4dc9}}


/* end https://en.wikipedia.org/ */
</style><span class="vanchor"><span class="vanchor-text">minimized average error</span></span></b>" using a larger <a href="Convolution_kernel" class="mw-redirect" title="Convolution kernel">kernel</a><sup id="cite_ref-Jarvis1976_3-0" class="reference"><a href="#cite_note-Jarvis1976-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup>
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle {\frac {1}{48}}{\begin{bmatrix}-&amp;-&amp;\#&amp;7&amp;5\\3&amp;5&amp;7&amp;5&amp;3\\1&amp;3&amp;5&amp;3&amp;1\end{bmatrix}}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mn>1</mn>
<mn>48</mn>
</mfrac>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mrow>
<mo>[</mo>
<mtable rowspacing="4pt" columnspacing="1em">
<mtr>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
<mtd>
<mi mathvariant="normal">#<!-- # --></mi>
</mtd>
<mtd>
<mn>7</mn>
</mtd>
<mtd>
<mn>5</mn>
</mtd>
</mtr>
<mtr>
<mtd>
<mn>3</mn>
</mtd>
<mtd>
<mn>5</mn>
</mtd>
<mtd>
<mn>7</mn>
</mtd>
<mtd>
<mn>5</mn>
</mtd>
<mtd>
<mn>3</mn>
</mtd>
</mtr>
<mtr>
<mtd>
<mn>1</mn>
</mtd>
<mtd>
<mn>3</mn>
</mtd>
<mtd>
<mn>5</mn>
</mtd>
<mtd>
<mn>3</mn>
</mtd>
<mtd>
<mn>1</mn>
</mtd>
</mtr>
</mtable>
<mo>]</mo>
</mrow>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle {\frac {1}{48}}{\begin{bmatrix}-&amp;-&amp;\#&amp;7&amp;5\\3&amp;5&amp;7&amp;5&amp;3\\1&amp;3&amp;5&amp;3&amp;1\end{bmatrix}}}</annotation>
</semantics>
</math></span><img src="./6745a860514efd85b6f9fc3e9b706a152d829be0.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -4.005ex; width:24.181ex; height:9.176ex;" alt="{\displaystyle {\frac {1}{48}}{\begin{bmatrix}-&amp;-&amp;\#&amp;7&amp;5\\3&amp;5&amp;7&amp;5&amp;3\\1&amp;3&amp;5&amp;3&amp;1\end{bmatrix}}}" loading="lazy"></span></dd></dl>
<div class="mw-heading mw-heading3"><h3 id="Ostromoukhov's_Variable_Error_Diffusion">Ostromoukhov's Variable Error Diffusion</h3></div>
<p>Later, <b>Victor Ostromoukhov</b> introduced a variable error diffusion method, which enhances dithering quality by dynamically adjusting the diffusion coefficients based on the <b>color values of the pixel’s RGB channels</b>.<sup id="cite_ref-4" class="reference"><a href="#cite_note-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p><p>The algorithm employs a <b>serpentine scan</b> instead of a traditional raster scan and modifies the <b>error buffer</b>, leading to <b>better dithering results</b>.
</p><p>According to his paper, this technique achieves a <b>blue-noise characteristic</b> while maintaining <b>lower computational complexity</b>. However, despite its advantages, the method did not gain widespread adoption at the time and was largely forgotten in later years.
</p><p><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle {\frac {1}{\text{sum}}}{\begin{bmatrix}-&amp;\#&amp;R\\DL&amp;D&amp;-\end{bmatrix}}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mn>1</mn>
<mtext>sum</mtext>
</mfrac>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mrow>
<mo>[</mo>
<mtable rowspacing="4pt" columnspacing="1em">
<mtr>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
<mtd>
<mi mathvariant="normal">#<!-- # --></mi>
</mtd>
<mtd>
<mi>R</mi>
</mtd>
</mtr>
<mtr>
<mtd>
<mi>D</mi>
<mi>L</mi>
</mtd>
<mtd>
<mi>D</mi>
</mtd>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
</mtr>
</mtable>
<mo>]</mo>
</mrow>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle {\frac {1}{\text{sum}}}{\begin{bmatrix}-&amp;\#&amp;R\\DL&amp;D&amp;-\end{bmatrix}}}</annotation>
</semantics>
</math></span><img src="./5237d9fb786830873b217411b15b7c82bcff3307.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -2.505ex; width:20.084ex; height:6.176ex;" alt="{\displaystyle {\frac {1}{\text{sum}}}{\begin{bmatrix}-&amp;\#&amp;R\\DL&amp;D&amp;-\end{bmatrix}}}" loading="lazy"></span>
</p><p>where "<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle R}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>R</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle R}</annotation>
</semantics>
</math></span><img src="./4b0bfb3769bf24d80e15374dc37b0441e2616e33.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.764ex; height:2.176ex;" alt="{\displaystyle R}" loading="lazy"></span>" denotes the right weight, "<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle DL}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>D</mi>
<mi>L</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle DL}</annotation>
</semantics>
</math></span><img src="./173965992da7fe0c4c46d0c2777d20a144f5fdd2.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:3.507ex; height:2.176ex;" alt="{\displaystyle DL}" loading="lazy"></span>" denotes the down-left weight, "<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle D}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>D</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle D}</annotation>
</semantics>
</math></span><img src="./f34a0c600395e5d4345287e21fb26efd386990e6.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.924ex; height:2.176ex;" alt="{\displaystyle D}" loading="lazy"></span>" denotes the down weight, and "<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle sum}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>s</mi>
<mi>u</mi>
<mi>m</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle sum}</annotation>
</semantics>
</math></span><img src="./dfcbbe8b8426463a9aef3611db156a3e2b115e91.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:4.461ex; height:1.676ex;" alt="{\displaystyle sum}" loading="lazy"></span>" represents the total of all weights.
</p>
<div class="mw-heading mw-heading2"><h2 id="Algorithm_description">Algorithm description</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1251242444">
/* start https://en.wikipedia.org/ */


.mw-parser-output .ambox{border:1px solid #a2a9b1;border-left:10px solid #36c;background-color:#fbfbfb;box-sizing:border-box}.mw-parser-output .ambox+link+.ambox,.mw-parser-output .ambox+link+style+.ambox,.mw-parser-output .ambox+link+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+style+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+link+.ambox{margin-top:-1px}html body.mediawiki .mw-parser-output .ambox.mbox-small-left{margin:4px 1em 4px 0;overflow:hidden;width:238px;border-collapse:collapse;font-size:88%;line-height:1.25em}.mw-parser-output .ambox-speedy{border-left:10px solid #b32424;background-color:#fee7e6}.mw-parser-output .ambox-delete{border-left:10px solid #b32424}.mw-parser-output .ambox-content{border-left:10px solid #f28500}.mw-parser-output .ambox-style{border-left:10px solid #fc3}.mw-parser-output .ambox-move{border-left:10px solid #9932cc}.mw-parser-output .ambox-protection{border-left:10px solid #a2a9b1}.mw-parser-output .ambox .mbox-text{border:none;padding:0.25em 0.5em;width:100%}.mw-parser-output .ambox .mbox-image{border:none;padding:2px 0 2px 0.5em;text-align:center}.mw-parser-output .ambox .mbox-imageright{border:none;padding:2px 0.5em 2px 0;text-align:center}.mw-parser-output .ambox .mbox-empty-cell{border:none;padding:0;width:1px}.mw-parser-output .ambox .mbox-image-div{width:52px}@media(min-width:720px){.mw-parser-output .ambox{margin:0 10%}}@media print{body.ns-0 .mw-parser-output .ambox{display:none!important}}


/* end https://en.wikipedia.org/ */
</style>
<p>Error diffusion takes a monochrome or color image and reduces the number of quantization levels.<sup id="cite_ref-5" class="reference"><a href="#cite_note-5"><span class="cite-bracket">[</span>5<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-6" class="reference"><a href="#cite_note-6"><span class="cite-bracket">[</span>6<span class="cite-bracket">]</span></a></sup> A popular application of error diffusion involves reducing the number of quantization states to just two per channel. This makes the image suitable for printing on binary printers such as black and white laser printers.
</p><p>In the discussion which follows, it is assumed that the number of quantization states in the error diffused image is two per channel, unless otherwise stated.
</p>
<div class="mw-heading mw-heading3"><h3 id="One-dimensional_error_diffusion">One-dimensional error diffusion</h3></div>
<p>The simplest form of the algorithm scans the image one row at a time and one pixel at a time. The current pixel is compared to a half-gray value. If it is above the value a white pixel is generated in the resulting image. If the pixel is below the half way brightness, a black pixel is generated. Different methods may be used if the target palette is not monochrome, such as thresholding with two values if the target palette is black, gray and white. The generated pixel is either full bright, or full black, so there is an error in the image. The error is then added to the next pixel in the image and the process repeats.
</p><p>The kernel for one-dimensional error diffusion is
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle 1{\begin{bmatrix}\#&amp;1\\-&amp;-\end{bmatrix}}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mn>1</mn>
<mrow class="MJX-TeXAtom-ORD">
<mrow>
<mo>[</mo>
<mtable rowspacing="4pt" columnspacing="1em">
<mtr>
<mtd>
<mi mathvariant="normal">#<!-- # --></mi>
</mtd>
<mtd>
<mn>1</mn>
</mtd>
</mtr>
<mtr>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
</mtr>
</mtable>
<mo>]</mo>
</mrow>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle 1{\begin{bmatrix}\#&amp;1\\-&amp;-\end{bmatrix}}}</annotation>
</semantics>
</math></span><img src="./8801dbc7047b127adb99ede9460a58049ffb5c59.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -2.505ex; width:10.436ex; height:6.176ex;" alt="{\displaystyle 1{\begin{bmatrix}\#&amp;1\\-&amp;-\end{bmatrix}}}" loading="lazy"></span></dd></dl>
<p>Or vertically
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle 1{\begin{bmatrix}\#&amp;-\\1&amp;-\end{bmatrix}}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mn>1</mn>
<mrow class="MJX-TeXAtom-ORD">
<mrow>
<mo>[</mo>
<mtable rowspacing="4pt" columnspacing="1em">
<mtr>
<mtd>
<mi mathvariant="normal">#<!-- # --></mi>
</mtd>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
</mtr>
<mtr>
<mtd>
<mn>1</mn>
</mtd>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
</mtr>
</mtable>
<mo>]</mo>
</mrow>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle 1{\begin{bmatrix}\#&amp;-\\1&amp;-\end{bmatrix}}}</annotation>
</semantics>
</math></span><img src="./0b4e7fb98fede0f9b2acd585340f28de68bccbcf.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -2.505ex; width:10.436ex; height:6.176ex;" alt="{\displaystyle 1{\begin{bmatrix}\#&amp;-\\1&amp;-\end{bmatrix}}}" loading="lazy"></span></dd></dl>
<div class="mw-heading mw-heading3"><h3 id="Two-dimensional_error_diffusion">Two-dimensional error diffusion</h3></div>
<p>One-dimensional error diffusion tends to have severe image artifacts that show up as distinct vertical lines. Two-dimensional error diffusion reduces the visual artifacts. The simplest algorithm is exactly like one-dimensional error diffusion, except that half the error is added to the next pixel, and half of the error is added to the pixel on the next line below.
</p><p>The kernel for two-dimensional error diffusion is
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle {\frac {1}{2}}{\begin{bmatrix}\#&amp;1\\1&amp;-\end{bmatrix}}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mn>1</mn>
<mn>2</mn>
</mfrac>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mrow>
<mo>[</mo>
<mtable rowspacing="4pt" columnspacing="1em">
<mtr>
<mtd>
<mi mathvariant="normal">#<!-- # --></mi>
</mtd>
<mtd>
<mn>1</mn>
</mtd>
</mtr>
<mtr>
<mtd>
<mn>1</mn>
</mtd>
<mtd>
<mo>−<!-- − --></mo>
</mtd>
</mtr>
</mtable>
<mo>]</mo>
</mrow>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle {\frac {1}{2}}{\begin{bmatrix}\#&amp;1\\1&amp;-\end{bmatrix}}}</annotation>
</semantics>
</math></span><img src="./274c76441afcca72f14dca4a733d07a2589be8bd.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -2.505ex; width:11.272ex; height:6.176ex;" alt="{\displaystyle {\frac {1}{2}}{\begin{bmatrix}\#&amp;1\\1&amp;-\end{bmatrix}}}" loading="lazy"></span></dd></dl>
<p>Further refinements can be made by: &nbsp;
</p><p>- Dispersing the error over a larger area (as seen in the matrices in the "Digital era" section).
</p><p>- Using a <b>serpentine scan</b> to reduce more artifacts.
</p><p>The sample image at the start of this article is an example of two-dimensional error diffusion.
</p>
<div class="mw-heading mw-heading3"><h3 id="Color_error_diffusion">Color error diffusion</h3></div>
<p>The same algorithms may be applied to each of the red, green, and blue (or cyan, magenta, yellow, black) channels of a color image to achieve a color effect on printers such as color laser printers that can only print single color values.
</p><p>However, better visual results may be obtained by first converting the color channels into a perceptive <a href="Color_model" title="Color model">color model</a> that will separate lightness, hue and saturation channels, so that a higher weight for error diffusion will be given to the lightness channel, than to the hue channel. The motivation for this conversion is that human vision better perceives small differences of lightness in small local areas, than similar differences of hue in the same area, and even more than similar differences of saturation on the same area.
</p><p>For example, if there is a small error in the green channel that cannot be represented, and another small error in the red channel in the same case, the properly weighted sum of these two errors may be used to adjust a perceptible lightness error, that can be represented in a balanced way between all three color channels (according to their respective statistical contribution to the lightness), even if this produces a larger error for the hue when converting the green channel. This error will be diffused in the neighboring pixels.
</p><p>In addition, <a href="Gamma_correction" title="Gamma correction">gamma correction</a> may be needed on each of these perceptive channels, if they don't scale linearly with the human vision, so that error diffusion can be accumulated linearly to these gamma-corrected linear channels, before computing the final color channels of the rounded pixel colors, using a reverse conversion to the native non gamma-corrected image format and from which the new residual error will be computed and converted again to be distributed to the next pixels.
</p>
<div class="mw-heading mw-heading3"><h3 id="Error_diffusion_with_several_gray_levels">Error diffusion with several gray levels</h3></div>
<p>Error Diffusion may also be used to produce output images with more than two levels (per channel, in the case of color images). This has application in displays and printers which can produce 4, 8, or 16 levels in each image plane, such as electrostatic printers and displays in compact mobile telephones. Rather than use a single threshold to produce binary output, the closest permitted level is determined, and the error, if any, is diffused as described above.
</p>
<div class="mw-heading mw-heading3"><h3 id="Printer_considerations">Printer considerations</h3></div>
<p>Most printers overlap the black dots slightly, so there is not an exact one-to-one relationship to dot frequency (in dots per unit area) and <a href="Lightness_(color)" class="mw-redirect" title="Lightness (color)">lightness</a>. Tone scale linearization may be applied to the source image to get the printed image to look correct.
</p>
<div class="mw-heading mw-heading3"><h3 id="Edge_enhancement_versus_lightness_preservation">Edge enhancement versus lightness preservation</h3></div>

<p>When an image has a transition from light to dark, the error-diffusion algorithm tends to
make the next generated pixel be black. Dark-to-light transitions tend to result in the next
generated pixel being white. This causes an edge-enhancement effect at the expense of gray-level reproduction accuracy. This results in error diffusion having a higher apparent resolution than other <a href="Halftone" title="Halftone">halftone</a> methods. This is especially beneficial with images with text in them, such as the typical facsimile.
</p><p>This effect shows fairly well in the picture at the top of this article. The grass detail and the text on the sign is well preserved,
and the lightness in the sky, containing little detail. A cluster-dot <a href="Halftone" title="Halftone">halftone</a> image of the same resolution would be much less sharp.
</p>
<div class="mw-heading mw-heading2"><h2 id="See_also">See also</h2></div>
<ul><li><a href="Floyd%E2%80%93Steinberg_dithering" title="Floyd–Steinberg dithering">Floyd–Steinberg dithering</a></li>
<li><a href="Halftone" title="Halftone">Halftone</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<div class="mw-references-wrap"><ol class="references">
<li id="cite_note-Ranger1931-1"><span class="mw-cite-backlink"><b><a href="#cite_ref-Ranger1931_1-0">^</a></b></span> <span class="reference-text">Richard Howland Ranger, "Facsimile system". United States Patent 1790723, issued 3 February 1931.</span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><b><a href="#cite_ref-2">^</a></b></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */


.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}


/* end https://en.wikipedia.org/ */
</style><cite id="CITEREFFloydSteinberg1976" class="citation journal cs1">Floyd, Robert W.; Steinberg, Louis (1976). "An Adaptive Algorithm for Spatial Grayscale". <i>Proceedings of the Society for Information Display</i>. <b>17</b> (2): <span class="nowrap">75–</span>77.</cite></span>
</li>
<li id="cite_note-Jarvis1976-3"><span class="mw-cite-backlink"><b><a href="#cite_ref-Jarvis1976_3-0">^</a></b></span> <span class="reference-text">J. F. Jarvis, C. N. Judice, and W. H. Ninke, "A survey of techniques for the display of continuous tone pictures on bilevel displays". Computer Graphics and Image Processing, <b>5</b>:1:13–40 (1976).</span>
</li>
<li id="cite_note-4"><span class="mw-cite-backlink"><b><a href="#cite_ref-4">^</a></b></span> <span class="reference-text">V. Ostromoukhov, "A Simple and Efficient Error-Diffusion Algorithm". <i>Proceedings of SIGGRAPH 2001</i>.</span>
</li>
<li id="cite_note-5"><span class="mw-cite-backlink"><b><a href="#cite_ref-5">^</a></b></span> <span class="reference-text"><cite id="CITEREFWong2005" class="citation book cs1">Wong, Ping Wah (2005). "Image Quantization, Halftoning, and Printing". <i>Handbook of Image and Video Processing</i>. pp.&nbsp;<span class="nowrap">925–</span>937. <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1016%2FB978-012119792-6%2F50117-0">10.1016/B978-012119792-6/50117-0</a>. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a>&nbsp;<bdi>978-0-12-119792-6</bdi>.</cite></span>
</li>
<li id="cite_note-6"><span class="mw-cite-backlink"><b><a href="#cite_ref-6">^</a></b></span> <span class="reference-text"><cite id="CITEREFShoopSaylesLitynski2002" class="citation book cs1">Shoop, Barry L.; Sayles, Andre H.; Litynski, Daniel M. (2002). "New Devices for Optoelectronics: Smart Pixels". <i>Fiber Optic Data Communication</i>. pp.&nbsp;<span class="nowrap">352–</span>421. <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1016%2FB978-012207892-7%2F50011-4">10.1016/B978-012207892-7/50011-4</a>. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a>&nbsp;<bdi>978-0-12-207892-7</bdi>.</cite></span>
</li>
</ol></div>
<div class="mw-heading mw-heading2"><h2 id="External_links">External links</h2></div>
<ul><li><a rel="nofollow" class="external text" href="https://archive.today/20130915112127/http://michal.is/projects/image-dithering-in-matlab/">Error diffusion in Matlab</a></li></ul></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2025-05-13" href="https://en.wikipedia.org/wiki/?title=Error_diffusion&amp;oldid=1290218477">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>

</body></html>